package com.sunshine.wrongquestionset.utils

import com.sunshine.wrongquestionset.room.entity.QuestionEntity
import com.sunshine.wrongquestionset.room.entity.QuestionInfoEntity
import java.sql.Time
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.max
import kotlin.math.min

/**
 * @author sunshine
 * @date 2021/4/11
 * 错题熟悉程度计算工具
 */
object FamiliarityUtils {

    private var nowTime: Long = 0L

    /**
     * 如何计算熟悉程度？
     * 熟悉程度显示时是一个0~1之间的浮点数
     * 但是实际存储可以是任何数
     * 结合遗忘曲线下降
     * 答题会上升
     */

    /**
     * 计算题目熟悉程度下降程度
     *
     * 当前计算方式：
     * 假设添加时熟悉程度为0，那么经过完全按照遗忘曲线复习，并且每次都满分的情况下，30天后，熟悉程度应该能正好达到1
     * 而这30天，每天熟悉程度都在下降，而只有6天是上升的
     * 所以，每次增加的是(得分/总分)* (1 / 6) * 2，这样增加6次，会正好增加2
     * 下降的是 (1 / 30)，这样，30天一共下降1
     * 两者相减，即可得到总体增加1，即从0增加到1
     * 这个方式有待考证
     *
     * @param dayDifference  上次做这道题和今天的时间差
     * @param familiarity    题目熟悉程度
     */
    private fun calculateFamiliarityReduce(dayDifference: Int, familiarity: Float): Float {
        if (dayDifference <= 0) return familiarity

        return familiarity - dayDifference * (1 / 30.0f)

//        return if (dayDifference == 1) familiarity * 0.75f
//        else calculateFamiliarityReduce(dayDifference - 1, familiarity * 0.75f)
    }

    /**
     * 计算题目熟悉程度上升程度
     *
     * 当前计算方式：
     * 假设添加时熟悉程度为0，那么经过完全按照遗忘曲线复习，并且每次都满分的情况下，30天后，熟悉程度应该能正好达到1
     * 而这30天，每天熟悉程度都在下降，而只有6天是上升的
     * 所以，每次增加的是(得分/总分)* (1 / 6) * 2，这样增加6次，会正好增加2
     * 下降的是 (1 / 30)，这样，30天一共下降1
     * 两者相减，即可得到总体增加1，即从0增加到1
     * 这个方式有待考证
     *
     * @param dayDifference  上次做这道题和今天的时间差
     * @param familiarity    题目熟悉程度
     */
    private fun calculateFamiliarityUp(dayDifference: Int, familiarity: Float, rightPercent: Float): Float {
        return if (dayDifference <= 0) familiarity
        else {
            familiarity + (rightPercent * 1 / 3.0f)
            //max(0.01f, min(1.0f, familiarity * rightPercent * 1.25f))
        }
    }

    /**
     * 整个列表中问题的熟悉程度下降
     */
    fun reduceFamiliarity(questionEntityList: List<QuestionEntity>?, dayDifference: Int): ArrayList<FamiliarityBean> {
        nowTime = Date().time

        val familiarityList = ArrayList<FamiliarityBean>()
        questionEntityList?.forEach {
            reduceFamiliarity(it, dayDifference = dayDifference)?.let { bean -> familiarityList.add(bean) }
        }

        return familiarityList
    }

    /**
     * 问题实体类的熟悉程度下降
     * @param lastTime 上次题目记录的时间，从questionInfo中找
     */
    fun reduceFamiliarity(questionEntity: QuestionEntity, nowTimeParam: Long, dayDifference: Int): FamiliarityBean? {
        nowTime = nowTimeParam

        return reduceFamiliarity(questionEntity, dayDifference)
    }

    private fun reduceFamiliarity(questionEntity: QuestionEntity, dayDifference: Int): FamiliarityBean? {
//        //今天距上一次复习的时间
//        val dayDifference = TimeUtils.dateDifference(questionEntity.lastTime, nowTime)
        //保证时间差是正确的
        return if (dayDifference > 0) {
            FamiliarityBean(questionEntity.id, calculateFamiliarityReduce(dayDifference, questionEntity.familiarity))
        } else {
            null
        }
    }

    fun upFamiliarity(questionEntityList: List<QuestionEntity>?, rightPercent: Float) {
        nowTime = TimeUtils.getNowTime()
        val familiarityList = ArrayList<FamiliarityBean>()
        questionEntityList?.forEach {
            upFamiliarity(it, rightPercent)?.let { bean -> familiarityList.add(bean) }
        }
    }

    /**
     * 题目熟悉程度上升
     */
    fun upFamiliarity(questionEntity: QuestionEntity, rightPercent: Float): FamiliarityBean? {
        nowTime = TimeUtils.getNowTime()
        //今天距上一次复习的时间
        val dayDifference = TimeUtils.dateDifference(questionEntity.lastTime, nowTime)

        //保证时间差是正确的
        return if (dayDifference > 0) {
            FamiliarityBean(questionEntity.id, calculateFamiliarityUp(dayDifference, questionEntity.familiarity, rightPercent))
        } else {
            null
        }
    }
}